﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Timers;

namespace BL
{
    /// <summary>
    /// Methods for creating testdata in the database.
    /// </summary>
    public static class Helpmethods
    {
        private static dbDataContext db;
        private static Random rand;

        public static Random Rand
        {
            get
            {
                if (rand == null)
                {
                    rand = new Random();
                }
                return rand;
            }
        }

        public static dbDataContext Db
        {
            get
            {
                if (db == null)
                {
                    db = new dbDataContext();
                }
                return db;
            }
        }

        public static void deleteAllData() 
        {
            Db.sp_DeleteAllData();
        }


        public static void createEmployee(int numberusers, int rigsperuser)
        {
            Console.WriteLine("Creating employees");
            for (int i = 0; i < numberusers; i++)
            {
                tEmployee emp = new tEmployee();
                emp.firstName = ((Firstnames)Rand.Next(Enum.GetNames(Type.GetType("BL.Firstnames")).Length)).ToString();
                emp.lastName = ((Lastnames)Rand.Next(Enum.GetNames(Type.GetType("BL.Lastnames")).Length)).ToString();
                Db.tEmployees.InsertOnSubmit(emp);
                Db.SubmitChanges();

                tAddress add = createAdress();

                tEmployeeAdress tea = new tEmployeeAdress();
                tea.addressId = add.addressId;
                tea.employeeId = emp.employeeId;
                Db.tEmployeeAdresses.InsertOnSubmit(tea);
                Db.SubmitChanges();

                tUser usr = createUser();

                tEmployeeUser teu = new tEmployeeUser();
                teu.employeeId = emp.employeeId;
                teu.userId = usr.userId;
                Db.tEmployeeUsers.InsertOnSubmit(teu);
                Db.SubmitChanges();

                tDevice dev = createDevice();

                tUserDevice tud = new tUserDevice();
                tud.deviceId = dev.deviceId;
                tud.userId = usr.userId;
                Db.tUserDevices.InsertOnSubmit(tud);
                Db.SubmitChanges();


                List<tRig> listorigs = Db.tRigs.ToList();
                List<tRig> userrigs = new List<tRig>();

                if (rigsperuser > listorigs.Count) rigsperuser = listorigs.Count; 
                for (int n = 0; n < rigsperuser; n++)
                {
                    int index = Rand.Next(0, listorigs.Count);
                    tRig rig = listorigs[index];
                    listorigs.RemoveAt(index);

                    userrigs.Add(rig);

                    tEmployeeRig terig = new tEmployeeRig();
                    terig.rigId = rig.rigId;
                    terig.employeeId = emp.employeeId;
                    Db.tEmployeeRigs.InsertOnSubmit(terig);
                    Db.SubmitChanges();

                }



                Console.WriteLine(emp.employeeId + ": " + emp.lastName + ", " + emp.firstName);
                Console.WriteLine(add.address + "\n" + add.tSePostalcode.postalcode + " " + add.tSePostalcode.city);
                Console.WriteLine("UserID/Pass: "+ usr.userId + "/" + usr.password);
                Console.WriteLine("DeviceID: " + dev.deviceId);


                Console.WriteLine(i + "/20");
            }
            Console.WriteLine("Done creating employees");
        }

        private static tDevice createDevice()
        {
            tDevice td = new tDevice();
            td.deviceId = "device_" + (Db.tDevices.Count() + 1);
            Db.tDevices.InsertOnSubmit(td);
            Db.SubmitChanges();

            foreach (tMessageType tmt in Db.tMessageTypes)
            {
                tDeviceMessageType tdmt = new tDeviceMessageType();
                tdmt.deviceId = td.deviceId;
                tdmt.messageTypeId = tmt.messageTypeId;
                tdmt.lastSync = new DateTime(1753, 1, 1, 0, 0, 0);
                Db.tDeviceMessageTypes.InsertOnSubmit(tdmt);
                Db.SubmitChanges();
            }

            return td;

        }

        private static tUser createUser()
        {
            string[] passwordslumper = {"12345", "password", "god"}; 
            tUser luser = new tUser();
            luser.password = passwordslumper[Rand.Next(0, passwordslumper.Length)];
            Db.tUsers.InsertOnSubmit(luser);
            Db.SubmitChanges();
            return luser;
        }

        private static tAddress createAdress()
        {
            tAddress add = new tAddress();
            add.country = "Sverige";
            add.postalcode = Db.tSePostalcodes.Skip(Rand.Next(Db.tSePostalcodes.Count())).First().postalcode;
            add.address = ((Address)Rand.Next(Enum.GetNames(Type.GetType("BL.Address")).Length)).ToString() + " " + Rand.Next(100);
            Db.tAddresses.InsertOnSubmit(add);
            Db.SubmitChanges();
            return add;
        }

        public static bool insertProducts()
        {
            if (Db.tArticleCategories.Count() > 0) return true;
            FileStream file = new FileStream("F:\\Masterkod\\BL\\Datafiles\\Other-Products.csv", FileMode.Open);
            StreamReader sr = new StreamReader(file);
            string line = "";
            tArticleCategory tac = new tArticleCategory();
            

            do
            {
                line = sr.ReadLine();
                
                if (line != null)
                {
                    string[] temp = line.Split(';');
                    if (!temp[0].Equals("") && !temp[0].Equals("Part Number"))
                    {
                        if ((temp.Length == 1))
                        {
                            tac = new tArticleCategory();
                            if (temp[0].Length > 64) 
                                temp[0] = temp[0].Remove(64);
                            tac.categoryDescription = temp[0];
                            Db.tArticleCategories.InsertOnSubmit(tac);
                            Db.SubmitChanges();
                        }
                        else
                        {
                            tArticle tart = new tArticle();
                            tart.articleCategoryId = tac.articleCategoryId;
                            if (temp[0].Length > 100) 
                                temp[0] = temp[0].Remove(100);
                            tart.name = temp[1];
                            Db.tArticles.InsertOnSubmit(tart);
                            Db.SubmitChanges();
                            Console.WriteLine(tart.articleId + ":" + tart.name + ", " + tart.tArticleCategory.categoryDescription);
                        }
                    }
                }

            } while (line != null);

            return false;
        }

        public static void insertPostalCodes()
        {


            FileStream file = new FileStream("F:\\Masterkod\\BL\\Datafiles\\Postnummer.csv", FileMode.Open);
            StreamReader sr = new StreamReader(file);
            

            string line = "";
            int no = 1;
            do
            {
                line = sr.ReadLine();
                if (line != null)
                {
                    string[] temp = line.Split(';');
                    tSePostalcode tspc = new tSePostalcode();
                    tspc.postalcode = int.Parse(temp[0]);
                    tspc.city = temp[1];
                    Console.Out.WriteLine(temp[1]);
                    try
                    {
                        Db.tSePostalcodes.InsertOnSubmit(tspc);
                        if (no == 30)
                        {
                            no = 0;
                            Db.SubmitChanges();
                        }
                    }
                    catch
                    {
                    }
                }
                no++;
            } while (line != null);
            Db.SubmitChanges();

        }

        public static int GetNumberOfRigs()
        {
            return Db.tRigs.Count();
        }

        public static void createRigs(int numberofrigs)
        {
            string[] rigdesc = {"Vatten", "Prospektering", "Värme", "Horisontell"};
            for (int i = 0; i < numberofrigs; i++)
            {
                tRig rig = new tRig();
                rig.description = rigdesc[Rand.Next(0, rigdesc.Length)] + "_" + Db.tRigs.Count();
                Db.tRigs.InsertOnSubmit(rig);
                Db.SubmitChanges();

                tStock stock = new tStock();
                stock.description = rig.description + "_stock_no_" + (rig.tRigStocks.Count + 1);
                Db.tStocks.InsertOnSubmit(stock);
                Db.SubmitChanges();

                tAddress add = createAdress();

                tRigStock rstock = new tRigStock();
                rstock.rigId = rig.rigId;
                rstock.stockId = stock.stockId;
                Db.tRigStocks.InsertOnSubmit(rstock);
                Db.SubmitChanges();

                tRigAdress radd = new tRigAdress();
                radd.addressId = add.addressId;
                radd.rigId = rig.rigId;
                Db.tRigAdresses.InsertOnSubmit(radd);
                Db.SubmitChanges();

                tStockAdress sadd = new tStockAdress();
                sadd.addressId = add.addressId;
                sadd.stockId = stock.stockId;
                Db.tStockAdresses.InsertOnSubmit(sadd);
                Db.SubmitChanges();

                Console.WriteLine("RigId/description: " + rig.rigId + "/" + rig.description);
                Console.WriteLine("stockId/description: " + stock.stockId + "/" + stock.description);
                Console.WriteLine(add.address + "\n" + add.tSePostalcode.postalcode + " " + add.tSePostalcode.city);
                Console.WriteLine("--------------------------------------------------------");                

            }
        }

        public static void GiveStock()
        {
            foreach (tStock ts in Db.tStocks)
            {
                Db.tStockPosistionStocks.InsertAllOnSubmit(createStockPositionStocks(ts, 10));
                Db.SubmitChanges();

                foreach (tStockPosistionStock tsps in ts.tStockPosistionStocks)
                {
                    createArticleStock(tsps);
                }
            }
        }

        private static void createArticleStock(tStockPosistionStock tsps)
        {
            tArticleStock tas = new tArticleStock();
            tas.stockId = tsps.stockId;
            tas.stockPositionId = tsps.stockPositionId;
            tArticle ta = Db.tArticles.Skip(Rand.Next(Db.tArticles.Count())).First();
            tas.articleId = ta.articleId;
            tas.sortId = ta.tArticleSorts.First().sortId;
            tas.stockBalance = Rand.Next(1, 100);
            tas.lastChange = GetRandomDateTime();
            Db.tArticleStocks.InsertOnSubmit(tas);
            Db.SubmitChanges();
        }

        private static DateTime GetRandomDateTime()
        {
            DateTime start = new DateTime(2005, 1, 1);
            int range = ((TimeSpan)(DateTime.Today - start)).Days;
            return start.AddDays(Rand.Next(range));
        }

        private static List<tStockPosistionStock> createStockPositionStocks(tStock ts, int p)
        {
            List<tStockPosistionStock> stockstockstock = new List<tStockPosistionStock>();
            for (int i = 0; i < p; i++)
            {
                tStockPosition tstpos = new tStockPosition();
                tstpos.stockPositionDesignation = "A" + p;
                Db.tStockPositions.InsertOnSubmit(tstpos);
                Db.SubmitChanges();

                tStockPosistionStock tsps = new tStockPosistionStock();
                tsps.stockId = ts.stockId;
                tsps.stockPositionId = tstpos.stockPositionId;
                Db.tStockPosistionStocks.InsertOnSubmit(tsps);
                Db.SubmitChanges();

            }

            return stockstockstock;
        }

        public static void MakeNoSort()
        {
            tSort ts = new tSort();
            ts.sortId = 0;
            ts.sortDescription = "(no sort)";
            Db.tSorts.InsertOnSubmit(ts);
            Db.SubmitChanges();

            foreach (tArticle ta in Db.tArticles)
            {
                tArticleSort tas = new tArticleSort();
                tas.articleId = ta.articleId;
                tas.sortId = Db.tSorts.First().sortId;
                Db.tArticleSorts.InsertOnSubmit(tas);
                Db.SubmitChanges();
            }
        }



        public static bool createMessageTypes()
        {
            if (Db.tMessageTypes.Count() != 0) return false;
            for (int i = 1; i <= Enum.GetValues(typeof(MessageType)).Length; i++)
            {
                tMessageType tmt = new tMessageType();
                tmt.messageTypeId = i;
                tmt.prio = 100;
                tmt.description = ((MessageType)i).ToString();
                tmt.allowDevice = true;
                tmt.lastChange = new DateTime(1753, 1, 1, 0, 0, 0, 0);
                Db.tMessageTypes.InsertOnSubmit(tmt);
                Db.SubmitChanges();
            }

            return true;
        }

        public static object[] GetAllEmployees()
        {
            return Db.tEmployees.ToArray();
        }

        public static bool CreateTransactions(object employee, object messagetype, string numberoftransactions)
        {
            int no;
            if (int.TryParse(numberoftransactions, out no));
            else return false;

            for (int i = 0; i < no; i++)
            {
                tTransactionLog tralg = new tTransactionLog();
                tEmployee temp = GetEmployee(employee);
                tMessageType tmt = GetMessageType(messagetype);
                tralg.incoming = true;
                tralg.messageTypeId = tmt.messageTypeId;
                tralg.userId = temp.tEmployeeUsers.First().userId;
                tralg.timestamp = GetRandomDateTime();
                tralg.messageContent = "Plopp " + Rand.Next();
                tralg.deviceId = temp.tEmployeeUsers.First().tUser.tUserDevices.First().deviceId;
                Db.tTransactionLogs.InsertOnSubmit(tralg);
                Db.SubmitChanges();
                Console.WriteLine(i + 1 + "/" + no);
            }

            return true;
        }

        private static tMessageType GetMessageType(object messagetype)
        {
            if (!messagetype.ToString().Equals("Randomize")) return (tMessageType)messagetype;
            else return Db.tMessageTypes.Skip(Rand.Next(Db.tMessageTypes.Count())).First();
        }

        private static tEmployee GetEmployee(object p)
        {
            if (!p.ToString().Equals("Randomize")) return (tEmployee)p;
            else return Db.tEmployees.Skip(Rand.Next(Db.tEmployees.Count())).First();
        }

        public static object[] GetAllMessageTypes()
        {
            return Db.tMessageTypes.ToArray();
        }

        public static object[] GetAllDevices()
        {
            return Db.tDevices.ToArray();
        }

        public static object[] GetAllUsers()
        {
            return Db.tUsers.ToArray();
        }

        public static tUser GetUserDevice(tDevice tDevice)
        {
            return tDevice.tUserDevices.First().tUser;
        }
    }
}
